/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package collections;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 *
 * @author Oksana_Moroz
 */
public class MyLinkedList<E> implements MyList<E> {

    private int size = 0;
    private MyNode<E> first;
    private MyNode<E> last;

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return (size == 0);
    }

    @Override
    public int indexOf(E elem) {
        int k = 0;
        for (MyNode<E> e = first; e != null; e = e.next) {
            if ((elem == null && e.item == null) || e.item.equals(elem)) {
                return k;
            }
            k++;
        }
        return -1;
    }

    @Override
    public boolean contains(E elem) {
        return (indexOf(elem) != -1);
    }

    @Override
    public Iterator<E> iterator() {
        return new MyListIterator();
    }

    @Override
    public void add(E elem) {
        MyNode<E> node = new MyNode<E>(elem, last, null);
        if (last != null) {
            last.next = node;
        }
        last = node;
        if (first == null) {
            first = node;
        }
        size++;
    }

    @Override
    public boolean remove(E elem) {
        if (first == null) {
            return false;
        }
        if ((elem == null && first.item == null) || first.item.equals(elem)) {
            first.next.prev = null;
            first = first.next;
            size--;
            return true;
        }
        for (MyNode<E> e = first; e.next != null; e = e.next) {
            if ((elem == null && e.next.item == null) || e.next.item.equals(elem)) {
                MyNode<E> temp = e.next;
                if (temp.next != null) {
                    temp.next.prev = e;
                }
                e.next = temp.next;
                size--;
                if (temp == last) {
                    last = e;
                }
                return true;
            }
        }
        return false;
    }
   
    private static class MyNode<E> {

        E item;
        MyNode<E> next;
        MyNode<E> prev;

        public MyNode(E item, MyNode<E> prev, MyNode<E> next) {
            this.item = item;
            this.next = next;
            this.prev = prev;
        }
    }

    private class MyListIterator implements Iterator<E> {

        private MyNode<E> current;

        public MyListIterator() {
            current = first;
        }

        @Override
        public boolean hasNext() {
            return (current != null);
        }

        @Override
        public E next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            E elem = current.item;
            current = current.next;
            return elem;
        }

        @Override
        public void remove() {
            MyLinkedList.this.remove(current.item);
        }
    }
}
